// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

#ifndef _INDIVIDUAL_H_
#define _INDIVIDUAL_H_

#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
\file
\ingroup	gio
\brief		Sample Person and Individual-Major Allelic Data (PLINK)
\details
	This header file is derived from the PLINK individual class which
	represents a sample person/individual in a data-set.<br>
	Allelic data bound to \ref individual is Individual-Major (dimension = People x SNPs).<br>
	The \ref individual structure is not involved in any statistical calculation
	but is used to store data from a PLINK-compatible text input file prior to
	a format conversion or encoding operation.<br>
	This \ref individual is also used in the unit tests which validate the I/O behavior 
	of the codebase against PLINK.
*/

/*! \brief Sample Person and Individual-Major Allelic Data (PLINK) */
struct individual {
	/*! \brief Family ID */
	char *fid;

	/*! \brief Individual ID */
	char *iid; 

	/*! \brief Paternal ID */
	char *pat; 

	/*! \brief Maternal ID */
	char *mat;

	/*! \brief Paternal Pointer Reference */
	struct individual *pp;

	/*! \brief Maternal Pointer Reference */
	struct individual *pm; 

	/*! \brief Permutation Pointer Reference */
	struct individual *pperson;

	/*! \brief Gender */
	BOOL sex;

	/*! \brief Text Gender Code */
	char *sexcode;

	/*! \brief Phenotype */
	double phenotype;

	/*! \brief Affected status for binary trait */
	BOOL aff;

	/*! \brief Phenotype missing */
	BOOL missing;

	/*! \brief Strata or Layer Index */
	int sol;  

	/*! \brief Person is a founder */
	BOOL founder; 

	/*! \brief Allelic data for position 1 */
	BOOL *one;

	/*! \brief Allelic data for position 2 */
	BOOL *two;

	/*! \brief Size of the position 1 allelic data array */
	int nOne;

	/*! \brief Size of the position 2 allelic data array */
	int nTwo;
};

/*! 
\brief Initialise an individual structure.
\details Pointers are set to NULL, counters to zero and booleans to FALSE.
\param [in,out] p Individual Structure
\returns 1 on success, 0 on failure.
*/
int individual_init(struct individual *p);

/*!
\brief Create an initialised individual structure.
\returns individual structure or NULL on failure
*/
struct individual* individual_create();

/*!
\brief Free the Attributes of an individual structure.
\param [in,out] person Individual Structure
\returns 1 on success, 0 on failure.
*/
int individual_free_attributes(struct individual *person);

/*!
\brief %Set the family ID of an individual.
\param [in,out] p Individual Structure
\param [in] value ID string
\returns 1 on success, 0 on failure.
*/
int individual_set_fid(struct individual *p, const char* value);

/*!
\brief %Set the ID of an individual.
\param [in,out] p Individual Structure
\param [in] value ID string
\returns 1 on success, 0 on failure.
*/
int individual_set_iid(struct individual *p, const char *value);

/*!
\brief %Set the maternal ID of an individual.
\param [in,out] p Individual Structure
\param [in] value ID string
\returns 1 on success, 0 on failure.
*/
int individual_set_mat(struct individual *p, const char *value);

/*!
\brief %Set the paternal ID of an individual.
\param [in,out] p Individual Structure
\param [in] value ID string
\returns 1 on success, 0 on failure.
*/
int individual_set_pat(struct individual *p, const char *value);

/*!
\brief %Set the Character 'gender' code of an individual.
\param [in,out] p Individual Structure
\param [in] value Gender code
\returns 1 on success, 0 on failure.
*/
int individual_set_sexcode(struct individual *p, const char* value);

/*!
\brief Append a element to the 'One' allelic array 
\param [in,out] c Individual Structure
\param [in] value The value
\returns 1 on success, 0 on failure.
*/
int individual_insert_one(struct individual *c, BOOL value);

/*!
\brief Append a element to the 'Two' allelic array 
\param [in,out] c Individual Structure
\param [in] value The value
\returns 1 on success, 0 on failure.
*/
int individual_insert_two(struct individual *c, BOOL value);

/*!
\brief Allocate storage to the 'One' allelic array.
\param [in,out] p Individual Structure
\param [in] size Amount to allocate
\returns 1 on success, 0 on failure.
*/
int individual_alloc_one(struct individual *p, int size);

/*!
\brief Allocate storage to the 'Two' allelic array.
\param [in,out] p Individual Structure
\param [in] size Amount to allocate
\returns 1 on success, 0 on failure.
*/
int individual_alloc_two(struct individual *p, int size);

#ifdef __cplusplus
}
#endif

#endif // _INDIVIDUAL_H_
